/*
 *  AUTHOR bangbang.song@gmail.com
 */

package com.cngphone.AnFetion;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.regex.Matcher;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.text.Spannable;
import android.text.method.LinkMovementMethod;
import android.text.method.MovementMethod;
import android.text.util.Linkify;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.cngphone.AnFetion.Fetion.FetionMessageProvider;
import com.cngphone.AnFetion.tools.LogUtil;
import com.cngphone.AnFetion.tools.SystemInfo;
import com.cngphone.AnFetion2.R;

/*
 * a simple fetion message viewer.
 */
public class FetionMessageHistory extends ListActivity 
                                  implements SimpleCursorAdapter.ViewBinder {
	private final static boolean LOCAL_LOG = false;
    private final static String TAG = "FeitonHistory";
    
    /* export the msgs for some purpose, oh ?*/
//    private File EXTERNAL_APP_DIR = null;
    private File EXTERNAL_DATA_DIR = null;
    private boolean mCanExported = false;
    
    private final static int DIALOG_ABOUTME = 1;
    private final static int DIALOG_CONFIRM_DEL = 2;

	private final static int MENU_RETURN = Menu.FIRST;
    /*
     * call the sender or receiver.
     */
    private final static int MENU_CALL = Menu.FIRST + 1;

    private final static int MENU_DEL = Menu.FIRST + 2;
    private final static int MENU_HELP = Menu.FIRST + 3;
    private final static int MENU_BUG = Menu.FIRST + 4;
    private final static int MENU_ABOUTME = Menu.FIRST + 5;
    private final static int MENU_FEEDBACK = Menu.FIRST + 6;
    private final static int MENU_EXPORT =  Menu.FIRST + 7;
    private final static int MENU_EXPORT_ALL = Menu.FIRST + 8;

    public final static String SHOW_MSGS_WHO = "com.bangbang.action.SHOW_MSGS_WHO";
    public final static String SHOW_MSGS = "com.bangbang.action.SHOW_MSGS";

   
    /*
     * u can dial the gays.
     */
    private String mFetionFriendUri;
    private FetionFriend mMe = null;
    private FetionFriend mFriend = null;
    
    private FetionService mFetionService = null;
    private ServiceConnection mConn = null;
    
    private Uri mContentUri = null;
    private Cursor mCursor = null; // for export & import
    
//    private SimpleCursorAdapter.ViewBinder mViewBinder = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        
        mConn = new ServiceConnection(){
        	public void onServiceDisconnected(ComponentName comName){
        		mFetionService = null;
        	};
        	public void onServiceConnected(ComponentName comName, IBinder ibinder){
        		mFetionService = ((FetionService.LocalBinder) ibinder).getService();
        		mMe = mFetionService.getMyself();
        		mFriend = getFriendById(mFetionFriendUri);
                setTitle("查看与 " + mFriend.getName() + " 的聊天记录");
        	}
        };

        if (null == getIntent() || null == getIntent().getData()) {
        	if (Settings.DEBUG) LogUtil.d(TAG, "the para the start " + 
        								   this.getClass().getCanonicalName() +
                                           "is incorrect");
            throw new IllegalArgumentException("incorrect para");
        }

        mContentUri = getIntent().getData();
        mFetionFriendUri = mContentUri.getLastPathSegment();
        LogUtil.d(TAG,"uri = " + mContentUri.toString());
        
		bindService(new Intent(FetionMessageHistory.this, FetionService.class),
    		    mConn , Context.BIND_AUTO_CREATE);

        mCursor = managedQuery(mContentUri, null, null, null, 
        		                     "_date DESC" /* reverse order*/
        		                     );
        // the cursor is always not null so (null != cursor) does not work.
        if (0 != mCursor.getCount()) {
            mCanExported = true;
            SimpleCursorAdapter adapter = 
            	new FetionSimpleCursorAdapter(this,
            							R.layout.fetion_message,
            							mCursor,
					                    new String[] { FetionMessageProvider.KEY_DATE, 
					            					   FetionMessageProvider.KEY_FROM,
					                                   FetionMessageProvider.KEY_MSG 
					                                  },
					                    new int[] {
					                            R.id.date, 
					                            R.id.from, 
					                            R.id.message 
					                            }
            	                        );
            // TODO custom my view 
//            adapter.setViewBindtrueer(this);

            setListAdapter(adapter);
        } else {
        	// FIXME: this can not work, why???
            // TODO:
            getListView().setEmptyView(findViewById(R.id.no_msg));

        }
        // nullpoint exception WHY???
//		mMe = mFetionService.getMyself();
//		mFriend = getFriendById(mFetionFriendUri);
//        setTitle("查看与 " + mFriend.FriendName + " 的聊天记录");
    }

	/*
     * id : [sip|tel]:xxxxxx  fetion ID
     */
    private FetionFriend getFriendById(String id){
    	ArrayList<FetionFriend> friends = mFetionService.getFriendManager().getBuddies();
    	for (FetionFriend a : friends) {
    		if (0 == a.Uri.indexOf(id)) {
    			return a;
    		}
    	}
    	
    	return null;
    }
    public boolean setViewValue(View view, Cursor cursor, int columnIndex){
    	String from = cursor.getString(cursor.getColumnIndexOrThrow("_from"));
    	if (cursor.getColumnIndex("_from") == columnIndex) {
    		((EditText)findViewById(R.id.from)).setText(getFetionFriendNameById(from));
    		
    		return false;
    	}
    	
    	return false;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(0, MENU_RETURN, 0, "返回聊天");
        menu.add(0, MENU_CALL, 0, "呼叫对方");
        if (mCanExported) {
            menu.add(0, MENU_DEL, 0, "删除消息");
        	menu.add(0, MENU_EXPORT, 0, "导出聊天记录");
        }
        menu.add(0, MENU_EXPORT_ALL, 0, "导出与所有好友聊天记录"	);
        menu.add(0, MENU_BUG, 0, "报告缺陷");
        menu.add(0, MENU_ABOUTME, 0, "关于飞信历史");
        menu.add(0, MENU_FEEDBACK, 0, "信息反馈");
        return true;
    }

	@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // TODO Auto-generated method stub
        switch (item.getItemId()) {
            case (MENU_RETURN): {
                finish();
                break;
            }
            case (MENU_CALL): {
            	callTheGay();
                break;
            }
            case (MENU_HELP): {
                if (Settings.DEBUG) 
                	LogUtil.d(TAG,"fetion message helper is not supported yet");
                break;
            }
            case (MENU_DEL): {
            	showDialog(DIALOG_CONFIRM_DEL);
            	break;
            }
            case (MENU_EXPORT): {
            	exportMessage();
               	break;
            }
            case (MENU_EXPORT_ALL): {
            	exprotMessageAll();
            	break;
            }
            case (MENU_BUG): {
            	sendBugToAthor();
            	break;
            }
            case (MENU_FEEDBACK): {
            	feedbackToAthor();
            	break;
            }
            case (MENU_ABOUTME): {
            	// TODO 
            	showDialogAboutme();
            	break;
            }
            default: {
                throw new IllegalArgumentException("unkown menuitem itemid=" + 
                		                           item.getItemId());
            }
        }
        return true;
    }
    private void delMessage(){
    	getContentResolver().delete(mContentUri, null, null);
    	Toast.makeText(getApplicationContext(), "消息历史已删除", Toast.LENGTH_SHORT);
    	finish();
    }
    private void callTheGay(){
    	if (null !=mFetionService) {
    		Uri telUri = getFetionTelUri();
    		if (null == telUri) {
    			LogUtil.d(TAG, "can not get the tel Uri");
    			say("抱歉！找不到对方电话号码");
    			finish();
    		}
    		startActivity(new Intent(Intent.ACTION_DIAL, telUri));
    	} else {
    		finish();
    	}
    }
    
    // TODO how add extra info in e-mail't body???
    private void feedbackToAthor(){
    	Uri mailUri = Uri.parse("mailto:bangbang.song@gmail.com");
    	Intent mail = new Intent(Intent.ACTION_SENDTO, mailUri);
    	String body = "\n\n\n\n----do NOT del text below this----\n";
    	
    	body += SystemInfo.getVersion(getApplicationContext()) + "\n";
    	body += SystemInfo.toStr() + "\n";
    	mail.putExtra(Intent.EXTRA_TEXT, body);
    	mail.putExtra(Intent.EXTRA_SUBJECT, 
    			      "FEEDBACK about fetionMessageHistory of AnFetion proj");
    	startActivity(mail); 
    }
    private void sendBugToAthor(){
    	Uri mailUri = Uri.parse("mailto:bangbang.song@gmail.com");
    	Intent mail = new Intent(Intent.ACTION_SENDTO, mailUri);
    	
    	String body = "\n\n\n\n----do NOT del text below this----\n";
    	
    	body += SystemInfo.getVersion(getApplicationContext()) + "\n";
    	body += SystemInfo.toStr() + "\n";
    	mail.putExtra(Intent.EXTRA_TEXT, body);
    	mail.putExtra(Intent.EXTRA_SUBJECT, 
    			      "BUG for fetionMessageHistory of AnFetion proj");
    	startActivity(mail); 	
    }
    
    private void showDialogAboutme(){
    	// TODO :
    	showDialog(DIALOG_ABOUTME);
//    	Dialog dialog = new Dialog(getApplicationContext());
//    	
//    	TextView tv = new TextView(getApplicationContext());
//    	tv.setText("bangbang@gmail.com");
//    	tv.setAutoLinkMask(Linkify.ALL);
//    	tv.setMovementMethod(LinkMovementMethod.getInstance());
//    	android.view.ViewGroup.LayoutParams lp = new LayoutParams(android.view.ViewGroup.LayoutParams.FILL_PARENT,
//    			                                                  android.view.ViewGroup.LayoutParams.FILL_PARENT);
//    	dialog.addContentView(tv, lp);
//    	dialog.show();
    }
    
    @Override
	protected Dialog onCreateDialog(int id) {
		// TODO Auto-generated method stub
    	// chain-like construct method
    	switch (id) {
    	case (DIALOG_ABOUTME): {
			AlertDialog dialog = new AlertDialog.Builder(this)
					   .setTitle("关于飞信历史记录")
//					   .setMessage(R.string.fetion_message_about)
					   .setPositiveButton("确定", new DialogInterface.OnClickListener(){
						   public void onClick(DialogInterface dialog, int whichButton){
							   
						   }
					   })
					   .setNegativeButton("返回", new DialogInterface.OnClickListener(){
						   public void onClick(DialogInterface dialog, int whichButton){
							   
						   }
					   })
					   .create();
			TextView tv = new TextView(getApplicationContext());
			tv.setText(R.string.fetion_message_about);
			// TODO how to auto-link strings???
			
			
//			Linkify.addLinks(tv, Pattern.compile("http://[a-zA-Z_./]*|[a-zA-Z_][a-zA-Z_.]*@[a-zA-Z][a-zA-Z._]*[a-zA-Z]*"), "", myMatchFilter, myTranFilter);
			
			// FIXME soooooooooo strange!!! when comment this, it works with no colored text.
			tv.setAutoLinkMask(Linkify.ALL);

//          in SDK, it say:
//			Sets whether the movement method will automatically be set to 
//			LinkMovementMethod if setAutoLinkMask(int) has been set to 
//			nonzero and links are detected in setText(char[], int, int). 
//			The default is true.
//			so we must disable it for using our customized MovementMethod.
			tv.setLinksClickable(false);
			/* 
			 * Calling startActivity() from outside of an Activity  
			 * context requires the FLAG_ACTIVITY_NEW_TASK flag. 
			 * Is this really what you want?
			 */
//			tv.setMovementMethod(LinkMovementMethod.getInstance());
			
			// FIXME: why can invacte my class ???
			// get it now , see tv.setLinksClickable();
			tv.setMovementMethod(new MyLinkMovementMethod());
			
			// FIXME requestFeature must be called before adding content
//			dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, 
//					                    WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
//			dialog.setContentView(tv);
			
			LinearLayout  l = new LinearLayout(getApplicationContext());
			LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
					                                                     ViewGroup.LayoutParams.FILL_PARENT);
			lp.setMargins(20, 4, 20, 4);
			l.addView(tv, lp);

			dialog.setView(l);
			
			return dialog;
    	}
    	case (DIALOG_CONFIRM_DEL): {
    		return new AlertDialog.Builder(this)
    				   .setTitle("真的要删除吗？")
    				   .setMessage(R.string.alert_del_message)
    				   .setPositiveButton("永久删除", new DialogInterface.OnClickListener(){
    					   public void onClick(DialogInterface dialog, int whichButton){
    						   delMessage();
    					   }
    				   })
    				   .setNegativeButton("不了", new DialogInterface.OnClickListener(){
    					   public void onClick(DialogInterface dialog, int whichButton){
    						   ;
    					   }
    				   })
    				   .create();
    	}
    	default: return null;
    	}
	}
    
    @Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
    	unbindService(mConn);
		super.onDestroy();
	}


	private class FetionSimpleCursorAdapter extends SimpleCursorAdapter {
		public FetionSimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
			super(context, layout, c, from, to);
		}

		@Override
		public void bindView(View view, Context context, Cursor cursor) {
			// TODO Auto-generated method stub
			super.bindView(view, context, cursor);
			String from = cursor.getString(cursor.getColumnIndex("_from"));
			((TextView)view.findViewById(R.id.from)).setText(getFetionFriendNameById(from));
		}
		
	}
	
	
	private String getFetionFriendNameById(String id) {
			/*  uri: [tel|sip]:xxxxxxx@fetion.com.cn@#$%^&&
			 *  id:  [tel|sip]:xxxxxxx		 */
//			if (it.Uri.matches(id + ".*")) {
			if (0 == mMe.Uri.indexOf(id)){
				return mMe.getName();
			} else if (0 == mFriend.Uri.indexOf(id)) {
				return mFriend.getName();
			} else {
				return null;
			}
	}

	private Uri getFetionTelUri(){
		if (null == mFriend.mobile_no) return null;
		return Uri.parse("tel:" + mFriend.mobile_no);
	}
	
	private void exprotMessageAll(){
		if (!android.os.Environment.getExternalStorageState().equals(
				android.os.Environment.MEDIA_MOUNTED)) {
			Toast.makeText(getApplicationContext(), "The SDCard is not ready", Toast.LENGTH_SHORT).show();
			return ;
		}
		String appDir = "AnFetion/message";
		EXTERNAL_DATA_DIR = new File(android.os.Environment.getExternalStorageDirectory(), appDir);
		if (!EXTERNAL_DATA_DIR.exists()) EXTERNAL_DATA_DIR.mkdirs();
		
		// vfat  file name convention
		String bakupTime = new SimpleDateFormat("_yyyy_MM_dd_HH_mm_ss").format(new Date());
		String fileName = "AllMessages" + bakupTime +".txt";
		File exportFile = new File(EXTERNAL_DATA_DIR , fileName);
		try {
			exportFile.createNewFile();
		} catch (IOException e) {
			LogUtil.e(TAG, "an Error when create the file" + exportFile.getName());
			e.printStackTrace();	
		} finally {
			
		}
		
		
//		how rename or del a file in android？？？
//		if (false == exportFile.exists()) {
//			try {
//				exportFile.createNewFile();
//				LogUtil.d(TAG, "a new file has created: " + exportFile.toString());
//			} catch (IOException e) {
//				
//			} finally {
//				
//			}
//		} else {
//			String bakupTime = new SimpleDateFormat("yyyy_MM_dd HH:mm:ss").format(new Date());
//			exportFile.renameTo(new File(exportFile.toString() + ".bak." + bakupTime));
//			
//			exportFile = new File(EXTERNAL_DATA_DIR , fileName);
//		}
		
		Uri uri = Uri.parse(FetionMessageProvider.Fetion.CONTENT_URI + "");
		Cursor cursor = managedQuery(uri, null, null, null, "_date DESC");
		if (0 == cursor.getCount()) {
			    say("U are no messages yet @@@");
				return;
		}
		cursor.moveToFirst();
		
		try {
			BufferedWriter bw = new BufferedWriter(new FileWriter(exportFile));
			LogUtil.i(TAG, "write the head ");
			
			// the head
			doExprotHead(bw, true);

			// the body
			doExportBody(bw, cursor);
			
		   	Toast.makeText(getApplicationContext(), "消息已保存到SD卡上", Toast.LENGTH_SHORT).show();
		} catch (IOException e) {
			
		} finally {
			cursor.moveToFirst();
		}
}
	
	private void exportMessage(){
//		if (!sdcardIsready()) return ;
		if (!android.os.Environment.getExternalStorageState().equals(
				android.os.Environment.MEDIA_MOUNTED)) {
			Toast.makeText(getApplicationContext(), "The SDCard is not ready", Toast.LENGTH_SHORT).show();
			return ;
		}
		String appDir = "AnFetion/message";
		EXTERNAL_DATA_DIR = new File(android.os.Environment.getExternalStorageDirectory(), appDir);
		if (!EXTERNAL_DATA_DIR.exists()) EXTERNAL_DATA_DIR.mkdirs();
		
		// vfat file name convention
		String bakupTime = new SimpleDateFormat("_yyyy_MM_dd_HH_mm_ss").format(new Date());
		String fileName = "message_with_" + mFriend.getName() +"" + bakupTime + ".txt";
		File exportFile = new File(EXTERNAL_DATA_DIR , fileName);
		try {
			exportFile.createNewFile();
		} catch (IOException e) {
			LogUtil.e(TAG, "an Error when create the file" + exportFile.getName());
			e.printStackTrace();
		} finally {
			
		}
		
		// TODO: how to rename or delete a file in andorid???
//		String fileName = "message_with_" + mFriend.getNickName() + "" + ".txt";
//		File exportFile = new File(EXTERNAL_DATA_DIR , fileName);
//		
//		if (false == exportFile.exists()) {
//			try {
//				exportFile.createNewFile();
//				LogUtil.d(TAG, "a new file has created: " + exportFile.toString());
//			} catch (IOException e) {
//
//			} finally {
//				
//			}
//		} else {
//			String bakupTime = new SimpleDateFormat("yyyy_MM_dd HH:mm:ss").format(new Date());
//			File bakFile = new File(exportFile.getName() + ".bak." + bakupTime);
//			if (!exportFile.renameTo(bakFile)) {
//				LogUtil.d(TAG,"can not rename ?? WHY ");
//				exportFile.delete();
//				
//			} else {
//				LogUtil.d(TAG, "rename to" + bakFile.getName());
//				LogUtil.d(TAG, "rename to" + exportFile.getName());
//			}
//			
//			try{
//				exportFile = new File(EXTERNAL_DATA_DIR , fileName);
//				exportFile.createNewFile();
//			} catch (IOException e) {
//					;
//			}
//		}
		
		try {
			BufferedWriter bw = new BufferedWriter(new FileWriter(exportFile));
			LogUtil.i(TAG, "write the head ");
			
			// the head
			doExprotHead(bw, false);

			// the body
			doExportBody(bw, mCursor);
			
		   	Toast.makeText(getApplicationContext(), "消息已保存到SD卡上", Toast.LENGTH_SHORT).show();
		} catch (IOException e) {
			
		} finally {
			mCursor.moveToFirst();
		}
		
	}
	private void doExprotHead(BufferedWriter bw, boolean all){
		try {
			String exportedTime = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date());
			
			// ALL line which begin with '#' will be IGNORED when imported.
			bw.write("#Protocol: fetion");
			bw.newLine();
			bw.write("#DB Version: 1");
			bw.newLine();
			bw.write("#Exported Time:" + exportedTime);
			bw.newLine();
			bw.write("#Author: bangbang.song@gmail.com");
			bw.newLine();
			if (false == all){
				bw.write("#Buddy's nick name:" + mFriend.getName());
			} else {
				bw.write("#All message RCD & SND by U");
			}
			bw.newLine();
			
			
			bw.flush();
		} catch (IOException e) {
			
		} finally {
			
		}
	}
	/*
	 * export teh messge body
	 */
	private void doExportBody(BufferedWriter bw, Cursor cursor){

		String from = cursor.getString(FetionMessageProvider.INDEX_FROM);		
		String to = cursor.getString(FetionMessageProvider.INDEX_TO);		
		try {
			if (cursor.moveToFirst()) {
				while (!cursor.isLast()) {

					String msg = cursor.getString(FetionMessageProvider.INDEX_MSG);
					String date = cursor.getString(FetionMessageProvider.INDEX_DATE);
					String id = cursor.getString(cursor.getColumnIndex("_id"));

					bw.newLine();
					bw.write("[msg_id = " + id + "]");
					bw.write("[from = " + from + "]");
					bw.write("[to = " + to + "]");
					bw.newLine();
					bw.write("date   : " + date);
					bw.newLine();
					bw.write("message: " + msg);
					bw.newLine();
					
					cursor.moveToNext();
				}
				
				bw.flush();
			}
		} catch (IOException e) {
			
		} finally {
			
		}
	}
	
/*
	private void importMessge(){
		
	}
*/
	
	private void say(String msg){
		Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT);
	}
	
	
	private void showWebpage(String url) {
		Intent web = new Intent(url);
		web.setAction(Intent.ACTION_VIEW);
		startActivity(web);
	}
	
	Linkify.MatchFilter myMatchFilter = new  Linkify.MatchFilter() {

		@Override
		public boolean acceptMatch(CharSequence s, int start, int end) {
			// FIXME this is not the best where do the right thing
			
			
			return true;	
		}
	};
	
	Linkify.TransformFilter myTranFilter = new Linkify.TransformFilter() {

		@Override
		public String transformUrl(Matcher match, String url) {
			// FIXME this is not the best where do the right thing
			
			if (url.startsWith("http")) {
				
				return url;
			}
			
			// mailto:xxx@xxx.xxx
			return url;
		}
		
	};
	
	// a wrapper name is better@@@
	// proxy???
	class MyLinkMovementMethod implements MovementMethod {
		private MovementMethod mParen = null;
		public MyLinkMovementMethod() {
			 mParen = LinkMovementMethod.getInstance();
		}
		

		
		private String mUrl = null;
		
		@Override
		public boolean onKeyDown(TextView widget, Spannable buffer, int keyCode,
				KeyEvent event) {
			// TODO Auto-generated method stub
			mUrl = buffer.toString();
			
			switch (keyCode) {
			case (KeyEvent.KEYCODE_ENTER): 
			case (KeyEvent.KEYCODE_DPAD_CENTER): {
				
//				android.util.AndroidRuntimeException: Calling startActivity() 
//			    from outside of an Activity  context requires the 
//			    FLAG_ACTIVITY_NEW_TASK flag. 
//			    Is this really what you want?
//				return action(buffer);
				
				action(mUrl);
				
				return true;
			}
			}
			return mParen.onKeyDown(widget, buffer, keyCode, event);
		}
		
		@Override
		public boolean onTouchEvent(TextView widget, Spannable buffer,
				MotionEvent event) {
			// TODO Auto-generated method stub
			mUrl = buffer.toString();
			
			LogUtil.v(TAG, "can u see me here ???");
			
			switch(event.getAction()) {
			case (MotionEvent.ACTION_UP): {
				action(mUrl);
				return true;
			}
			}
			return mParen.onTouchEvent(widget, buffer, event);
		}
		
		private boolean action(String url) {
			boolean isWeb = url.startsWith("http");
			boolean isMail = !isWeb;
			if (isWeb) {
				showWebpage(url);
				
				return true;
			} else if (isMail) {
				sendBugToAthor();
				
				return true;
			}
			
			return false;
		}
		
		@Override
		public boolean onKeyOther(TextView view, Spannable text, KeyEvent event) {
			// TODO Auto-generated method stub
			return mParen.onKeyOther(view, text, event);
		}
		@Override
		public boolean onKeyUp(TextView widget, Spannable buffer, int keyCode,
				KeyEvent event) {
			// TODO Auto-generated method stub
			return mParen.onKeyUp(widget, buffer, keyCode, event);
		}
		@Override
		public void onTakeFocus(TextView view, Spannable text, int dir) {
			// TODO Auto-generated method stub
			mParen.onTakeFocus(view, text, dir);
		}
		@Override
		public boolean onTrackballEvent(TextView widget, Spannable text,
				MotionEvent event) {
			// TODO Auto-generated method stub
			return mParen.onTrackballEvent(widget, text, event);
		}
		@Override
		public boolean canSelectArbitrarily() {
			// TODO Auto-generated method stub
			return mParen.canSelectArbitrarily();
		}
		@Override
		public void initialize(TextView widget, Spannable text) {
			// TODO Auto-generated method stub
			mParen.initialize(widget, text);
		}
	}

}


